package cn.xspace.module.other.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import com.xspace.android.xafcommon.db.dbsub.BaseDbMg;
import com.xspace.android.xafcommon.util.StringUtils;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Handler;
import android.util.Log;

public class AmrAudioPlayer implements MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,MediaPlayer.OnErrorListener{
    private static final String TAG = "AmrAudioPlayer";

    private static AmrAudioPlayer playerInstance = null;

    private long alreadyReadByteCount = 0;

    private MediaPlayer audioPlayer;
    private Handler handler = new Handler();

    private  String cacheFileName = "audioCacheFile";
    private File cacheFile;
    private int cacheFileCount = 0;

    // 用来记录是否已经从cacheFile中复制数据到另一个cache中
    private boolean hasMovedTheCacheFlag;

    private boolean isPlaying;
    private Activity activity;

    private boolean isChaingCacheToAnother;
    private String tempPath;
    private PlayCallBack mPlayCallBack;
    private AmrAudioPlayer() {
    }

    public static AmrAudioPlayer getAmrAudioPlayerInstance() {
        if (playerInstance == null) {
            synchronized (AmrAudioPlayer.class) {
                if (playerInstance == null) {
                    playerInstance = new AmrAudioPlayer();
                }
            }
        }
        return playerInstance;
    }

    public void initAmrAudioPlayer(Activity activity,PlayCallBack mPlayCallBack) {
        this.activity = activity;
        this.mPlayCallBack=mPlayCallBack;
    }
    private boolean isCacheFile(String filePath) {
        try {
            File f = new File(filePath);
            if (f.exists()) {
                if (f.isFile()) {
                  return true;
                }
            }
        }catch (Exception e){
            Log.e(TAG, "----------------delete Exception: " + e.getMessage());
        }
        return  false;
    }
    private void deleteExistCacheFile() {
        try {
            File f = new File(activity.getCacheDir(),cacheFileName);
            if (f.exists()) {
                if (f.isFile()) {
                    f.delete();
                }
            }
        }catch (Exception e){
            Log.e(TAG, "----------------delete Exception: " + e.getMessage());
        }
    }

    private void initCacheFile() {
        cacheFile = null;
        cacheFile = new File(activity.getCacheDir(), cacheFileName);
    }

    public void start(String playUrls) {
        isPlaying = true;
        playUrl=playUrls;
        cacheFileName= playUrls.substring(playUrls.lastIndexOf("/") + 1,playUrls.length());
            isChaingCacheToAnother = false;
            setHasMovedTheCacheToAnotherCache(false);
            new Thread(new NetAudioPlayerThread()).start();
    }

    public void stop() {
        isPlaying = false;
        isChaingCacheToAnother = false;
        setHasMovedTheCacheToAnotherCache(false);
        releaseAudioPlayer();
        cacheFile = null;
    }

    private void releaseAudioPlayer() {
        if (audioPlayer != null) {
            try {
                if (audioPlayer.isPlaying()) {
                    audioPlayer.pause();
                }
                audioPlayer.release();

            } catch (Exception e) {
            }finally {
                mPlayCallBack.stopPlaying();
            }
        }
    }
    public interface PlayCallBack{
        void startDownLoad();
        void stopDownLoad(boolean isSuc);
        void startPlaying();
        void stopPlaying();
    }



    private boolean hasMovedTheCacheToAnotherCache() {
        return hasMovedTheCacheFlag;
    }

    private void setHasMovedTheCacheToAnotherCache(boolean result) {
        hasMovedTheCacheFlag = result;
    }
   private String  playUrl;
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        System.out.println("--------------------------------onBufferingUpdate");
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        System.out.println("--------------------------------onCompletion");
        stop();
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        System.out.println("--------------------------------onPrepared");
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        stop();
        return false;
    }

    public boolean isPlaying(){
        return  isPlaying;
    }

    private class NetAudioPlayerThread implements Runnable {
        // 从接受数据开始计算，当缓存大于INIT_BUFFER_SIZE时候开始播放
        private final int INIT_AUDIO_BUFFER = 2 * 1024;
        // 剩1秒的时候播放新的缓存的音乐
        private final int CHANGE_CACHE_TIME = 1000;

        public void run() {
            String tempPath= BaseDbMg.getInstance().getAudioMsgDb().findAudioPath(playUrl);
            System.out.println("------------------------------tempPath:"+tempPath);
            System.out.println("------------------------------!isCacheFile(tempPath):"+!isCacheFile(tempPath));
            if(StringUtils.isNull(tempPath)||!isCacheFile(tempPath)) {
                try {
                    mPlayCallBack.startDownLoad();
                    URLConnection socket = createSocketConnectToServer();
                    receiveNetAudioThenPlay(socket);
                } catch (Exception e) {
                    Log.e(TAG, e.getMessage() + "从服务端接受音频失败。。。");
                    System.out.println("------------------------------从服务端接受音频失败:");
                    isPlaying=false;
                    mPlayCallBack.stopDownLoad(false);
                }
            }else{
                try {
                    cacheFile = new File(tempPath);
                    firstTimeStartPlayer();
                } catch (Exception e) {
                    isPlaying=false;
                    System.out.println("------------------------------音频失败:");
                    Log.e(TAG, "-------------------------"+e.getMessage() + "音频失败。。。");
                }
            }
        }

        private URLConnection createSocketConnectToServer() throws Exception {
            // 构造URL
            URL url = new URL(playUrl);
            // 打开连接
            URLConnection con = url.openConnection();
            return con;
        }

        private void receiveNetAudioThenPlay(URLConnection socket) throws Exception {
            deleteExistCacheFile();
            initCacheFile();
            boolean isDown=false;
            InputStream inputStream = socket.getInputStream();
            FileOutputStream outputStream = new FileOutputStream(cacheFile);
            final int BUFFER_SIZE = 100 * 1024;// 100kb buffer size
            byte[] buffer = new byte[BUFFER_SIZE];
            // 收集了10*350b了之后才开始更换缓存
            int testTime = 10;
            try {
                alreadyReadByteCount = 0;
                while (isPlaying) {
                    int numOfRead = inputStream.read(buffer);
                    System.out.println("-------------------------------numOfRead:"+numOfRead);
                    if (numOfRead <= 0) {
                        break;
                    }
                    alreadyReadByteCount += numOfRead;
                    outputStream.write(buffer, 0, numOfRead);
                    outputStream.flush();

                }
                BaseDbMg.getInstance().getAudioMsgDb().insertInTransaction(cacheFile.getPath(),playUrl);
                mPlayCallBack.stopDownLoad(true);
                isDown=true;
            } catch (Exception e) {
                errorOperator();
                e.printStackTrace();

            } finally {
                buffer = null;
                if (inputStream != null) {
                    inputStream.close();
                    inputStream = null;
                }
                if (outputStream != null) {
                    outputStream.close();
                    outputStream = null;
                }
                if(isDown)
                firstTimeStartPlayer();
            }
        }
        private void firstTimeStartPlayer() {
               try {
                   Runnable r = new Runnable() {
                       public void run() {
                           try {
                               mPlayCallBack.startPlaying();
                               setHasMovedTheCacheToAnotherCache(true);
                               audioPlayer = createAudioPlayer(cacheFile);
                               audioPlayer.start();
                           } catch (Exception e) {
                               System.out.println("------------------===play e:"+e.getMessage());
                               mPlayCallBack.stopPlaying();
                           } finally {
                           }
                       }
                   };
                   handler.post(r);
               }catch (Exception e){
                   e.printStackTrace();
               }
        }

        private MediaPlayer createAudioPlayer(File audioFile) throws IOException {
            MediaPlayer mPlayer = new MediaPlayer();
            mPlayer.setOnBufferingUpdateListener(AmrAudioPlayer.this);
            mPlayer.setOnPreparedListener(AmrAudioPlayer.this);
            mPlayer.setOnCompletionListener(AmrAudioPlayer.this);
            mPlayer.setOnErrorListener(AmrAudioPlayer.this);
            FileInputStream fis = new FileInputStream(audioFile);
            mPlayer.reset();
            mPlayer.setDataSource(fis.getFD());
            mPlayer.prepare();
            return mPlayer;
        }

        private void errorOperator() {
        }
    }

}
